import * as cloudDb from '@agconnect/database-server';
import { resource } from './model/resource';
import { topic } from './model/topic';
import { user_topic } from './model/user_topic';
import { user_like } from './model/user_like';
import { user_history } from './model/user_history';
import { collect } from './model/collect';
import { ListResp } from './model/ListResp';
import { HomeResp } from './model/HomeResp';
import { topic_resource } from './model/topic_resource';
import { ResourceResp } from './model/ResourceResp';
import * as agc from '@agconnect/common-server';
import * as Utils from './utils/Utils.js';

const ZONE_NAME = "HarmonyOSDeveloper";

export class DatabaseHelper {
  logger;
  cloudDbZone;

  constructor(context, logger) {
    this.logger = logger;
    const credential = Utils.getCredential(context, logger);
    try {
      // 初始化AGCClient
      logger.info("begin to init agcClient");
      let agcClient;
      try {
        agcClient = agc.AGCClient.getInstance();
      } catch {
        agc.AGCClient.initialize(credential);
        agcClient = agc.AGCClient.getInstance();
      }
      // 初始化AGConnectCloudDB实例
      logger.info("begin to init cloudDb");
      let cloudDbInstance;
      try {
        cloudDbInstance = cloudDb.AGConnectCloudDB.getInstance(agcClient);
      } catch {
        cloudDb.AGConnectCloudDB.initialize(agcClient);
        cloudDbInstance = cloudDb.AGConnectCloudDB.getInstance(agcClient);
      }
      // 创建CloudDBZoneConfig配置对象，并设置云侧CloudDB zone名称，打开Cloud DB zone实例
      const cloudDBZoneConfig = new cloudDb.CloudDBZoneConfig(ZONE_NAME);
      this.cloudDbZone = cloudDbInstance.openCloudDBZone(cloudDBZoneConfig);
    } catch (err) {
      logger.error("init CloudDBZoneWrapper error: " + err);
    }
  }

  async queryResource(userid) {
    let likedIds = [];
    let collectedIds = [];
    let historyIds = [];
    let homeResp: HomeResp;
    if (!this.cloudDbZone) {
      console.log("CloudDBClient is null, try re-initialize it");
      return;
    }
    try {
      // if (userid) {
      //   likedIds = await this.queryLikedIds(userid);
      //   collectedIds = await this.queryCollectedIds(userid);
      //   historyIds = await this.queryHistoryIds(userid);
      // }
      let topics: topic[] = await this.queryTopic();
      let feedList = await this.queryResourceByePage(userid, "feed", likedIds, collectedIds, historyIds, topics);
      let article = await this.queryResourceByePage(userid, "article", likedIds, collectedIds, historyIds, topics);
      let bannerList = await this.queryBannerResource(userid, likedIds, collectedIds, historyIds, topics);
      homeResp = new HomeResp(
        bannerList,
        feedList,
        article
      )
      return homeResp;
    } catch (error) {
      this.logger.info("query resource error " + error);
    }
  }

  async queryTopicResIds(userId, queryNum, type) {
    let resourceIds = [];
    // 先查询该userid关联了哪些topic
    const topicQuery = cloudDb.CloudDBZoneQuery.where(user_topic).equalTo('user_id', userId);
    const topicResp = await this.cloudDbZone.executeQuery(topicQuery);
    let topicData = topicResp.getSnapshotObjects();
    this.logger.info("query user success ");
    console.log('resp=>', topicData.length);
    let followedTopicIds = [];
    for (let i = 0; i < topicData.length; i++) {
      followedTopicIds.push(topicData[i].getTopic_id());
    }
    resourceIds = await this.queryFollowedTopicResourceIds(followedTopicIds, queryNum, type);
    return resourceIds;
  }

  async queryFollowedTopicIds(userId) {
    // 先查询该userid关联了哪些topic
    const topicQuery = cloudDb.CloudDBZoneQuery.where(user_topic).equalTo('user_id', userId);
    const topicResp = await this.cloudDbZone.executeQuery(topicQuery);
    let topicData = topicResp.getSnapshotObjects();
    this.logger.info("query queryFollowedTopicIds success ");
    console.log('resp=>', topicData.length);
    let followedTopicIds = [];
    for (let i = 0; i < topicData.length; i++) {
      followedTopicIds.push(topicData[i].getTopic_id());
    }
    return followedTopicIds;
  }

  async queryBannerResource(userid, likedIds, collectedIds, historyIds, topics) {
    let resourceData = []
    let resList = [];
    try {
      const resourceQuery = cloudDb.CloudDBZoneQuery.where(resource);
      resourceQuery.equalTo('tag', 2);
      const resourceResp = await this.cloudDbZone.executeQuery(resourceQuery);
      resourceData = resourceResp.getSnapshotObjects();
      this.logger.info("query queryBannerResource success ");
      console.log('resp=>', resourceData.length);
      if (resourceData.length > 0) {
        resList = this.getResourceList(resourceData, likedIds, collectedIds, historyIds, topics)
      }
    } catch (error) {
      this.logger.info("query queryBannerResource error " + error);
    } finally {
      return resList;
    }
  }

  getResourceList(resourceData, likedIds, collectedIds, historyIds, topics) {
    let resList = [];
    for (let i = 0; i < resourceData.length; i++) {
      let dataQ: resource = resourceData[i];
      resList.push(new ResourceResp(
        dataQ.getId(),
        dataQ.getTitle(),
        dataQ.getBrief(),
        dataQ.getHeader_src(),
        dataQ.getType(),
        dataQ.getWeb_url(),
        dataQ.getPublish_date(),
        this.getTopicNames(topics, dataQ.getTopics()),
        dataQ.getViews_count(),
        dataQ.getCollect_count(),
        dataQ.getLikes_count(),
        dataQ.getTag(),
        dataQ.getBanner_src(),
        dataQ.getMedia_src(),
        // likedIds.indexOf(dataQ.getId()) !== -1, // isLiked
        // collectedIds.indexOf(dataQ.getId()) !== -1, // isCollected
        // historyIds.indexOf(dataQ.getId()) !== -1 // isViewed
        null, // isLiked
        null, // isCollected
        null // isViewed
      ))
    }
    return resList;
  }

  async queryResourceByePage(userId, type, likedIds, collectedIds, historyIds, topics) {
    let resourceData = [];
    let listResp;
    let resList = [];
    let totalCount = 0;
    try {
      const resourceQuery = cloudDb.CloudDBZoneQuery.where(resource);
      resourceQuery.equalTo('type', type);
      if (userId) { // 如果用户传了userId 则查询用户关注主题下的资源数据
        const followedTopicIds = await this.queryFollowedTopicIds(userId);
        const resourceIds = await this.queryFollowedTopicResourceIds(followedTopicIds, 10, type);
        totalCount = resourceIds.length;
        resourceQuery.in('id', resourceIds);
      } else { // 否在直接查询资源列表
        totalCount = await this.cloudDbZone.executeCountQuery(resourceQuery, 'id');
      }
      resourceQuery.limit(10, 0);
      const resourceResp = await this.cloudDbZone.executeQuery(resourceQuery);
      resourceData = resourceResp.getSnapshotObjects();
      this.logger.info("query queryFeedResource success ");
      console.log('resp=>', resourceData.length);
      console.log('totalCount=>', totalCount);
      if (resourceData.length > 0) {
        resList = this.getResourceList(resourceData, likedIds, collectedIds, historyIds, topics)
      }
      listResp = new ListResp(
        1,
        10,
        Math.ceil(totalCount / 10),
        totalCount,
        totalCount > 10,
        resList
      )
    } catch (error) {
      this.logger.info("query queryFeedResource error " + error);
    } finally {
      return listResp;
    }
  }

  async queryTopic() {
    // 查询所有主题
    const cloudDBZoneQuery = cloudDb.CloudDBZoneQuery.where(topic);
    const resp = await this.cloudDbZone.executeQuery(cloudDBZoneQuery);
    let listData = resp.getSnapshotObjects();
    this.logger.info("query topic success ");
    console.log('queryTopic listData=>', listData.length);
    return listData;
  }

  getTopicNames(topics: topic[], tidStr: string) {
    let topicNames = []
    let topicIds: string[] = tidStr.split(',');
    for (let index = 0; index < topicIds.length; index++) {
      const tid = topicIds[index];
      let name: topic[] = topics.filter(tp => tp.getId() === tid);
      topicNames.push(name[0].getName())
    }
    return topicNames;
  }

  async queryFollowedTopicResourceIds(topicIds, queryNum, type) {
    let resourceIds = [];
    let totalCount = 0;
    try {
      const topicResourceQuery = cloudDb.CloudDBZoneQuery.where(topic_resource);
      if (topicIds.length > 0) {
        topicResourceQuery.in('topic_id', topicIds);
      }
      topicResourceQuery.equalTo('type', type);
      totalCount = await this.cloudDbZone.executeCountQuery(topicResourceQuery, 'resource_id');
      console.log('totalCount=>', totalCount);
      // topicResourceQuery.limit(queryNum, 0);
      const topicResourceResp = await this.cloudDbZone.executeQuery(topicResourceQuery);
      let topicResourceRespData = topicResourceResp.getSnapshotObjects();
      this.logger.info("query topicResourceRespData success ");
      console.log('resp topicResourceRespData=>', topicResourceRespData.length);
      for (let index = 0; index < topicResourceRespData.length; index++) {
        const element: topic_resource = topicResourceRespData[index];
        if (!resourceIds.includes(element.getResource_id())) {
          resourceIds.push(element.getResource_id());
        }
      }
    } catch (error) {
      this.logger.info("query resource error " + error);
    } finally {
      return resourceIds;
    }
  }
}



